package algoritmo.funcion4;

import java.util.Random;

import utils.Utils;

import algoritmo.Cromosoma;
import algoritmo.Funcion;
import algoritmo.funcion1.CromosomaFuncion1;

public class CromosomaFuncion4 extends Cromosoma{

	public CromosomaFuncion4(double[] xmin, double[] xmax, double tol,
			Funcion funcion, int numVariables) {
		super(xmin, xmax, tol, funcion, numVariables);
		// Establecemos la longitud de cada cromosoma
		int long_max = 0;
		longitudCromosoma = new int[numVariables];
		for (int i = 0; i < numVariables; i++) {
			setLongitudCromosoma(tol, i);
			if (getLongitudCromosoma(i) > long_max) {
				long_max = getLongitudCromosoma(i);
			}
		}
		// Creamos la matriz de genes
		this.genes = new boolean[2][long_max];
	}

	@Override
	public double evalua() {
		double[] x;
		//x = fenotipo();
		// Creamos el vector de fenotipos
		this.fenotipo = new double[numVariables];
		for (int i = 0; i < numVariables; i++) {
			this.fenotipo[i] = (float) Utils.bin2dec(genes[i], longitudCromosoma[i])
					/ (Math.pow((double) 2, (double) longitudCromosoma[i]) - 1);
			this.fenotipo[i] = xmin[i] + (xmax[i] - xmin[i]) * this.fenotipo[i];
		}
		x = this.fenotipo;
		return funcion.fx(x, this.numVariables);
	}

	@Override
	public void inicializaCromosoma() {
		Random random = new Random();
		// Se generan los genotipos para cada variable
		// Tenemos dos variables: x e y
		for (int i = 0; i < numVariables; i++) {
			for (int j = 0; j < longitudCromosoma[i]; j++) {
				genes[i][j] = random.nextBoolean();
			}
		}
	}

	protected void setLongitudCromosoma(double tol, int indice) {
		double x = 1 + ((xmax[indice] - xmin[indice]) / tol);
		longitudCromosoma[indice] = (int) Math.ceil(Math.log(x) / Math.log((double)2));
	}

	public double[] fenotipo() {
		double[] x = new double[numVariables];
		for (int i = 0; i < numVariables; i++) {
			x[i] = (float) Utils.bin2dec(genes[i], longitudCromosoma[i])
					/ (Math.pow((double) 2, (double) longitudCromosoma[i]) - 1);
			x[i] = xmin[i] + (xmax[i] - xmin[i]) * x[i];
		}
		return x;
	}

	public CromosomaFuncion4 Clone() {
		CromosomaFuncion4 clon = new CromosomaFuncion4(this.xmin, this.xmax,
				this.tol, this.funcion, this.numVariables);
		clon.setAptitud(this.getAptitud());
		clon.setGenes(this.getGenes());
		for (int i = 0; i < numVariables; i++) {
			clon.setLongitudCromosoma(this.tol, i);
		}
		clon.setPunt_acum(this.punt_acum);
		clon.setPuntuacion(this.puntuacion);
		clon.setFenotipo(this.fenotipo);
		return clon;
	}
}
